<?php

/**
 * Class OAuthResponse
 * Edit from original library OAuth-PHP of Marc Worrell <marcw@pobox.com>
 * 
 * Helper class to generate XML response from result
 *
 * @editor: Phong Linh <langxangvn@gmail.com>
 * @see http://code.google.com/p/oauth-php
*/
class OAuthResponse {
	
	/**
	 * This is variable _xml description
	 */
	protected $_xml = null;
	
	/**
	 * This is variable _status description
	 */
	protected $_status = null;
	
	/**
	 * This is variable _error description
	 */
	protected $_error = null;
	
	/**
	 * This is variable _error description
	 */
	protected $_useAttributes = true;

	/* [ XML FORMAT CONFIG ] */
	
	/**
	 * Response XML tag name
	 */
	public static $RSP_TAG = 'rsp';		
	
	/**
	 * Response status attribute name
	 */
	public static $RSP_STAT_ATTR = 'stat';		
	
	/**
	* Response status success value
	*/
	public static $RSP_STAT_OK_ATTR = 'ok';	
	
	/**
	* Response status fail value
	*/
	public static $RSP_STAT_FAIL_ATTR = 'fail';
	
	/**
	* Error XML tag name
	*/
	public static $ERR_TAG = 'err';
	
	/**
	* Error code attribute name
	*/
	public static $ERR_CODE_ATTR = 'code';
	
	/**
	* Error message attribute name
	*/
	public static $ERR_MSG_ATTR = 'msg';	
	
	/**
	 * This is method __construct
	 *
	 * @param array $response This is a description
	 * @param mixed $status This is a description
	 * @param array $useAttributes This is a description	 
	 * @return mixed This is the return value description
	 *
	 */
	public function __construct(array $response = array(), $status = true, $useAttributes = true) {
		$this->_xml = simplexml_load_string(
			'<?xml version="1.0" encoding="utf-8"?><' . 
			self::$RSP_TAG . '></' . self::$RSP_TAG . '>'
			);
		
		// use attribute or not
		$this->_useAttributes = $useAttributes;
		
		// append status
		$this->appendStatus($status);
				
		if (count($response) > 0) { // if have response data
			$this->appendResponse($this->_xml, $response); 
		}
	}
	
	/**
	 * This is method appendStatus
	 *
	 * @param mixed $status This is a description
	 * @return mixed This is the return value description
	 *
	 */
	public function appendStatus($status = true) {
		if (is_null($this->_status)) {
			if($this->_useAttributes) {
				if ($status === true) {
					$this->_xml->addAttribute(self::$RSP_STAT_ATTR, 
						self::$RSP_STAT_OK_ATTR);
				} elseif ($status === false) {
					$this->_xml->addAttribute(self::$RSP_STAT_ATTR, 
						self::$RSP_STAT_FAIL_ATTR);
				} else {
					throw new Exception('Invalid response status');
				}
			} else {
				if ($status === true) {
					$this->_xml->addChild(self::$RSP_STAT_ATTR, self::$RSP_STAT_OK_ATTR);
				} elseif ($status === false) {
					$this->_xml->addChild(self::$RSP_STAT_ATTR, self::$RSP_STAT_FAIL_ATTR);
				} else {
					throw new Exception('Invalid response status');
				}
			}
			
			$this->_status = $status;
		} else {
			throw Exception('Response already has status');    
		}
	}
	
	/**
	 * This is method appendResponse
	 *
	 * @param mixed $xml This is a description
	 * @param array $response This is a description
	 * @return mixed This is the return value description
	 *
	 */
	public function appendResponse($xml, array $response) {
		foreach ($response as $key => $val) {
			if (is_array($val)) {
				$child = $xml->addChild($key);
				$this->appendResponse($child, $val);
			} else {
				if($this->_useAttributes) {
					$xml->addAttribute($key, $val);					
				} else {
					$xml->addChild($key, $val);
				}
			}
		}
	}
	
	/**
	 * This is method appendError
	 *
	 * @param mixed $code This is a description
	 * @param mixed $message This is a description
	 * @return mixed This is the return value description
	 *
	 */
	public function appendError($code, $message) {
		if (is_null($this->_error)) {
			$error = self::$ERR_TAG;
			
			$this->_xml->addChild($error);
			
			if($this->_useAttributes) {
				$this->_xml->$error->addAttribute(self::$ERR_CODE_ATTR, $code);
				$this->_xml->$error->addAttribute(self::$ERR_MSG_ATTR, $message);
			} else {
				$this->_xml->$error->addChild(self::$ERR_CODE_ATTR, $code);
				$this->_xml->$error->addChild(self::$ERR_MSG_ATTR, $message);
			}
			
			$this->_error = array('code' => $code, 'msg' => $message);
		} else {
			throw Exception('Response already has error');    
		}
	}	
	
	/**
	 * This is method get
	 *
	 * @param mixed $att This is a description
	 * @return mixed This is the return value description
	 *
	 */
	public function get($att = 'content', $stringOutput = true) {
		switch ($att) {
			case 'content':
				if($stringOutput) {
					return $this->_xml->asXml();
				} else {
					return $this->_xml;
				}
				
			case 'error':
				if($stringOutput) {
					return $this->_error->asXml();
				} else {
					return $this->_error;
				}
			
			default:
				throw new Exception('Not supported.');
		}
	}
	
	/**
	 * This is method xml
	 *
	 * @param mixed $att This is a description
	 * @return mixed This is the return value description
	 *
	 */
	public function xml($att = 'content') {
		switch ($att) {
			case 'content':
				return $this->_xml;
				
			case 'error':
				return $this->_error;
			
			default:
				throw new Exception('Not supported.');
		}
	}
	
	/**
	 * This is method generate
	 *
	 * @param array $response This is a description
	 * @param mixed $status This is a description
	 * @param mixed $useAttributes This is a description
	 * @param mixed $stringOutput This is a description
	 * @return mixed This is the return value description
	 *
	 */	
	public static function generate(array $response = array(), $status = true, 
		$useAttributes = true, $stringOutput = true, $lname = false, 
		$iname = false) 
	{
		$result = null;
		
		if($lname !== false && $iname !== false) {
			$result = new OAuthResponse(array($lname => array()), $status, $useAttributes);
			$xml = $result->_xml->children();
			foreach($response as $i => $item) {
				$result->appendResponse($xml, array($iname => $item));
			}			
		} else {
			$result = new OAuthResponse($response, $status, $useAttributes);
		}
		
		if($stringOutput) {
			return $result->_xml->asXml();
		} else {
			return $result->_xml;
		}
	}
	
	/**
	 * This is method plain
	 *
	 * @param array $response This is a description
	 * @return mixed This is the return value description
	 *
	 */	
	public static function plain(array $response) {
		foreach ($response as $key => $val) {
			$content .= $key . '=' . $val . '&';
		}
		
		return substr($content, 0, strlen($content) - 1);
	}
	
	/**
	 * *
	 *
	 * @param mixed $code This is a description
	 * @param mixed $message This is a description
	 * @param mixed $useAttributes This is a description
	 * @param mixed $stringOutput This is a description
	 * @return mixed This is the return value description
	 *
	 */	
	public static function error($code, $message, $useAttributes = true, $stringOutput = true) {
		$result = new OAuthResponse(array(), false, $useAttributes);
		$result->appendError($code, $message);
		
		if($stringOutput) {
			return $result->_xml->asXml();
		} else {
			return $result->_xml;
		}
	}	
}

?>